#ifndef CX_OS_CRITICAL_H
#define CX_OS_CRITICAL_H
#include "cx_typedef.h"
#include "cx_os_config.h"

extern cx_uint32_t uxCriticalNesting;
__attribute__((__always_inline__)) static inline cx_uint32_t EntryCriticalFromISR(void)
{
    cx_uint32_t ulReturn, ulNewBASEPRI = MAX_SYSCALL_INTERRUPT_PRIORITY;
    asm volatile(
        "push {r1}\n"
        "movs r1, %1\n"
        "mrs %0, basepri \n"
        "msr basepri, r1\n"
        "pop {r1}\n"
        "dsb \n"
        "isb \n"
        :"=r"(ulReturn)
        :"r"(ulNewBASEPRI)
        :"memory"
        );
    return ulReturn;
}
__attribute__((__always_inline__)) static inline void ExitCriticalFromISR(cx_uint32_t ulBASEPRI)
{
    asm volatile("msr basepri,%0"::"r"(ulBASEPRI):"memory");
}
__attribute__((__always_inline__)) static inline void EntryCritical(void)
{
    disableInterrupt();
    uxCriticalNesting++;
    if ( uxCriticalNesting == 1 )
    {
        configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
    }
}
__attribute__((__always_inline__)) static inline void ExitCritical( void )
{
    configASSERT( uxCriticalNesting );
    uxCriticalNesting--;
    if ( uxCriticalNesting == 0 )
    {
        enableInterrupt();
    }
}
#endif